<template>
  <h1 class="title">{{ year }}</h1>
  <el-row :gutter="20">
    <el-col :sm="12" :md="8" :lg="6" v-for="(item, index) in calendar" :key="index">
      <section class="calendar">
        <p class="calendar-title">{{ item.month }}</p>
        <table class="calendar-body">
          <tr class="calendar-week">
            <th v-for="week in calendarWeeks" :key="week">{{ week }}</th>
          </tr>
          <tbody>
            <tr v-for="(week, index) in item.formatDays" :key="index">
              <th v-for="day in week" :key="day.dayIndex">
                <div
                  class="day"
                  :class="{
                    isHoliday: day.isHoliday,
                    isWeekend: day.isWeekend,
                    isInLieu: day.isInLieu
                  }"
                >
                  {{ day.date || '' }}
                  <span class="vacation">{{ day.vacation }}</span>
                </div>
              </th>
            </tr>
          </tbody>
        </table>
      </section>
    </el-col>
  </el-row>
</template>

<script setup>
import { ref } from 'vue'
import dayjs from 'dayjs'
import { cloneDeep } from 'lodash'
import chineseDays from 'chinese-days'
import { lunarDays, solarDays } from './config'
import { chunkArray } from '@/utils/utils'
const year = dayjs().year()
const beginDate = ref(`${year}-01-01`)
const endDate = ref(`${year}-12-31`)
const calendar = ref([])

const calendarWeeks = ref(['一', '二', '三', '四', '五', '六', '日'])

// 获取节假日
const getVacation = (date) => {
  const lunarDate = chineseDays.getLunarDate(date)
  const dateMonth = dayjs(date).format('M-D')
  const vacation = isLunarVacation(lunarDate) || solarDays[dateMonth]
  if (vacation) {
    return vacation.name
  }
  const weekDay = dayjs(date).day()
  if (weekDay === 0 || weekDay === 6) {
    return 'weekend'
  }
  return null
}
// 判断是否农历节假日
const isLunarVacation = (date) => {
  const lunarDate = `${date.lunarMon}-${date.lunarDay}`
  if (lunarDate === '12-29') {
    // 判断12-29是不是除夕
    const date = lunarDate.date
    const nextDate = dayjs(date).add(1, 'day').format('YYYY-MM-DD')
    const lunarNextDate = chineseDays.getLunarDate(nextDate)
    if (lunarNextDate.lunarMon === 1) {
      return lunarDays['12-30']
    }
  } else {
    return lunarDays[lunarDate]
  }
  return null
}

const getHolidaysInRange = (beginDate, endDate) => {
  const holidays = chineseDays.getHolidaysInRange(beginDate, endDate, false)
  return holidays
}

// 整理日历数据
const getCalendar = (beginDate, endDate) => {
  let isLastDate = false
  const beginDateObj = dayjs(beginDate)
  const endDateObj = dayjs(endDate)
  let currentDate = beginDateObj
  let monthObj = {}
  let dayIndex = 0
  const calendar = []
  do {
    const month = currentDate.month() + 1
    if (monthObj.month !== month) {
      // 新一个月
      if (monthObj.month) {
        // 将上一个月的数据保存
        calendar.push(cloneDeep(monthObj))
      }
      // 新一个月
      monthObj = { month, days: [] }
    }
    // 处理当前日期的信息
    const dateTime = currentDate.format('YYYY-MM-DD')
    const date = currentDate.date()
    const dayDetail = chineseDays.getDayDetail(dateTime)
    const weekDay = currentDate.day()
    const isWeekend = weekDay === 0 || weekDay === 6
    const isWork = dayDetail.work
    const vacationName = !isWork && dayDetail.name.includes(',') ? dayDetail.name.split(',')[1] : ''
    const isHoliday = chineseDays.isHoliday(dateTime) //假期：不准确，把周末都算进去了
    const isInLieu = chineseDays.isInLieu(dateTime) //调休日：不准备，都返回false
    const dayObj = {
      dayIndex,
      dateTime,
      date: currentDate.date(),
      weekDay,
      isWeekend: !isWork && isWeekend, //周末：周末并且不需要上班
      isHoliday: !isWork && vacationName, //节假日：无需上班且有节假日名称（周末无需上班无节假日名称）
      vacation: vacationName,
      // vacation: getVacation(dateTime),
      dayDetail,
      isInLieu: isWork && isWeekend //补班：周末但是需要上班的
      // work: dayDetail.work,
      // vacation: !dayDetail.work ? dayDetail.name : ''
    }
    monthObj.days.push(dayObj)
    dayIndex++
    if (currentDate.isSame(endDateObj)) {
      isLastDate = true
      calendar.push(cloneDeep(monthObj))
    } else {
      currentDate = currentDate.add(1, 'day')
    }
  } while (!isLastDate)
  return calendar
}
const calendars = getCalendar(beginDate.value, endDate.value)
// 补充数据，是每月数据是从周1开始（非周一前面占位）
calendars.forEach((month) => {
  const firstDate = month.days[0]
  const firstDay = firstDate.weekDay
  if (firstDay !== 1) {
    const iffset = firstDay === 0 ? 7 - 1 : firstDay - 1
    for (let i = 0; i < iffset; i++) {
      month.days.unshift({
        date: '',
        weekDay: '',
        isCurrentMonth: false,
        isToday: false,
        isWeekend: false,
        isHoliday: false,
        isWork: false,
        isVacation: false,
        isSolarHoliday: false,
        isLunarHoliday: false
      })
    }
  }
  month.formatDays = chunkArray(month.days, 7)
})

calendar.value = calendars
</script>

<style lang="scss" scoped>
.title {
  text-align: center;
  font-size: 30px;
  font-weight: bolder;
  padding: 10px;
}
.calendar {
  border: 1px solid #ededed;
  border-radius: 5px;
  margin-bottom: 20px;
  .calendar-title {
    padding: 5px 10px;
    text-align: center;
    font-weight: bolder;
    font-size: 26px;
  }
  .calendar-body {
    width: 100%;
    .calendar-week {
      // display: flex;
      // justify-content: space-between;
      .calendar-week-item {
        padding: 5px;
      }
    }
    .day {
      width: 100%;
      height: 100%;
      margin: 1px;
      border-radius: 2px;
      position: relative;
      display: flex;
      flex-direction: column;
      justify-content: center;

      &.isHoliday {
        background-color: rgba($color: #ff0000, $alpha: 0.3);
        color: #ff0000;
        &::after {
          content: '休';
          position: absolute;
          top: 0;
          left: 2px;
          font-size: 8px;
        }
      }
      &.isWeekend {
        color: #ff0000;
      }
      &.isInLieu {
        background-color: rgba($color: #333333, $alpha: 0.3);
        &::after {
          content: '班';
          position: absolute;
          top: 0;
          left: 2px;
          font-size: 8px;
        }
      }
      .vacation {
        font-size: 10px;
      }
    }
  }
}
</style>
